#include <stdlib.h>
#include <stdio.h>

#include "event.h"
#include "eventHandler.h"

///////////////////////////////////////////
//////// EventHandlerConsumer  ///////////
//////////////////////////////////////////

EventHandlerConsumer::EventHandlerConsumer(::Ice::CommunicatorPtr& c, 
										const std::string& host, 
										EventHandler* e) : EventConsumer(c, host)
{
	evh = e;
}

EventHandlerConsumer::~EventHandlerConsumer()
{
	
}

void EventHandlerConsumer::push(const ::Collaboration::Event& evt,
                  const ::Ice::Current& c)
{
	Event event(evt, c.adapter->getCommunicator());
	
	unsigned int i;
	::std::vector<ListeningObject*> v = evh->getObjects();
	for (i=0; i<v.size(); i++)
	{
		v[i]->listen(event);
	}
}

///////////////////////////////////////////
//////// EventHandlerSupplier   ///////////
//////////////////////////////////////////

EventHandlerSupplier::EventHandlerSupplier(::Ice::CommunicatorPtr& c, 
										const std::string& host, 
										EventHandler* e) : EventSupplier(c, host)
{
	evh = e;
}

EventHandlerSupplier::~EventHandlerSupplier()
{
	
}

///////////////////////////////////////////
////////      EventHandler     ///////////
//////////////////////////////////////////

EventHandler::EventHandler(::Ice::CommunicatorPtr& c, const ::std::string& host)
{
	comm = c;
	channel_out = new EventHandlerSupplier(c, host, this);
	channel_input = new EventHandlerConsumer(c, host, this);
}

EventHandler::~EventHandler()
{
	objects.clear();
	
	delete channel_input;
	delete channel_out;
}

::std::vector<ListeningObject*> EventHandler::getObjects()
{
	return objects;
}
	
int EventHandler::getPosObj(const ListeningObject& obj)
{
	unsigned int i;
	for (i=0; i<objects.size(); i++)
	{
		if (objects[i] == &obj)
		{
			return i;
		}
	}
	
	return -1;
}	

void EventHandler::push(const Event& ev)
{	
	Ice::Current c;
	channel_out->push(ev.internalEvent(), c);
}
	
void EventHandler::registerObject(ListeningObject& obj)
{
	if (getPosObj(obj) == -1)
	{
		objects.push_back(&obj);
	}
}
	
void EventHandler::unregisterObject(ListeningObject& obj)
{	
	int pos = getPosObj(obj);
	if (pos != -1)
	{
		ListeningObject* obj = objects[pos];
		objects[pos] = objects[objects.size()-1];
		objects[objects.size()-1] = obj;
		
		objects.pop_back();
		
		delete obj;
	}
}

::Ice::CommunicatorPtr EventHandler::getCommunicator()
{
	return comm;
}
